
//
//  XMLViewController.m
//  网络
//
//  Created by hfzhangzhang on 2018/4/10.
//  Copyright © 2018年 hfzhangzhang. All rights reserved.
//

#import "XMLViewController.h"
#import "Video.h"

@interface XMLViewController ()<NSXMLParserDelegate>
//MARK: - XML 解析所需要的素材
//1.可变数组
@property(nonatomic,strong)NSMutableArray * videos;
//2.当前解析的节点(模型)
@property(nonatomic,strong)Video * currentVideo;
//3.拼接字符串
@property(nonatomic,strong)NSMutableString * elementString;
@end

@implementation XMLViewController


/*
 JSON
 XML
 是曾经最流行的网络传输数据格式, W3C主推,IBM & 微软
 
 XML -> 可扩展"标记"语言
 <标记></标记>
 <标记>标记内容</标记>
 <标记 属性1="属性"属性2="属性2">标记内容</标记>
 特点:
 -阅读方便,美观大方
 
 解析方式
 -DOM  MAC提供的解析方法,iOS中无法直接使用
 - 原因:内存开销巨大!
 - 可读可写
 - 将数据已树形结构加载到内存
 -SAX   iOS提供的解析方式
 - 内存开销小
 - 只读
 - 速度快
 - 从上到下,顺序解析的过程
 
 -----------SAX解析的过程----------
 1.打开文档(准备)
 2.开始节点
 <videos>
 <video videoId="1">
 <name>
 <length>
 3.发现节点内容(一个节点内容,可能会读取很多次!)
 01.C
 语言-
 语法预览
 320
 ....
 4.结束节点
 </name>
 </length>
 ....
 </video>
 </videos>     (最后一个节点)
 判断文档是否解析结束,如果没有就继续
 5.文档解析完成!
 
 在实际开发中,XML的解析是用过NSXMLParser的对象来实现!具体的实现过程,是通过"五个代理"方法不断循环,来完成XML解析!
 */

//MARK: - 懒加载
-(NSMutableArray *)videos
{
    if (!_videos) {
        _videos = [NSMutableArray array];
    }
    return _videos;
}

-(NSMutableString *)elementString
{
    if (!_elementString) {
        _elementString = [NSMutableString string];
    }
    return  _elementString;
}


- (void)viewDidLoad {
    [super viewDidLoad];
    [self loadData];
}

- (void)loadData{
    //1.url
    NSURL * url = [NSURL URLWithString:@"http://192.168.31.180/videos.xml"];
    
    //2.request
    NSURLRequest * request = [NSURLRequest requestWithURL:url cachePolicy:1 timeoutInterval:10.0];
    
    //3.链接发送请求,获取数据
    [NSURLConnection sendAsynchronousRequest:request queue:[[NSOperationQueue alloc]init] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {
        //实例化  NSXMLParser
        NSXMLParser * parser = [[NSXMLParser alloc]initWithData:data];
        //一旦解析开始,后的的工作,都是通过代理方法来监听实现的
        parser.delegate = self;
        //解析器解析
        [parser parse];
    }];
}


#pragma mark - <NSXMLParserDelegate>
//1.打开文档(准备)
-(void)parserDidStartDocument:(NSXMLParser *)parser
{
    NSLog(@"1.打开文档(准备).");
    //清空数组,保证解析多次能进行!!
    [self.videos removeAllObjects];
}
//2.开始节点 (元素 - element) elementName : 节点名称  attributeDict :包含在开始节点内的扩展描述
-(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary<NSString *,NSString *> *)attributeDict{
    NSLog(@"2.开始节点  %@  %@",elementName,attributeDict);
    //如果elementName 是 video
    if ([elementName isEqualToString:@"video"]) {
        //1.新建一个Video 模型对象
        self.currentVideo = [[Video alloc]init];
        //2.这是这个对象的videoID属性
        self.currentVideo.videoId = @([attributeDict[@"videoId"] intValue]);
    }
    //清空字符串
    [self.elementString setString:@""];
    
}
//3.发现节点内容(一个节点内容,可能会读取很多次!)
-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
    NSLog(@"3.发现节点内容  %@",string);
    //拼接字符串
    [self.elementString appendString:string];
    
}

//4.结束节点
-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
    NSLog(@"4.结束节点  %@",elementName);
    //如果 element 是 video ,添加模型到数组
    if ([elementName isEqualToString:@"video"]) {
        [self.videos addObject:self.currentVideo];
    }else if([elementName isEqualToString:@"name"]){
        self.currentVideo.name = self.elementString;
    }else if([elementName isEqualToString:@"length"]){
        self.currentVideo.length = @(self.elementString.intValue);
    }else if([elementName isEqualToString:@"videoURL"]){
        self.currentVideo.videoURL = self.elementString;
    }else if([elementName isEqualToString:@"imageURL"]){
        self.currentVideo.imageURL = self.elementString;
    }else if([elementName isEqualToString:@"desc"]){
        self.currentVideo.desc = self.elementString;
    }else if([elementName isEqualToString:@"teacher"]){
        self.currentVideo.teacher = self.elementString;
    }
}

//5.文档解析完成!
-(void)parserDidEndDocument:(NSXMLParser *)parser
{
    NSLog(@"5.文档解析完成!  %@",self.videos);
}
//6.出现错误(只要是网络开发,就需要处理错误!)
-(void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError
{
    NSLog(@"发生错误  %@",parseError);
}

@end
